#include <QtGui>
#include <QtOpenGL>

#include "glwidget.h"

GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget)
    : QGLWidget(parent, shareWidget),
      mNeedDeleteTexture(0)
{
    mPictureWidth = 320;
    mPictureHeight = 240;
    mPictureData = new uint8_t[mPictureWidth*mPictureHeight*4];
    mMutex = new CMutex;

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT( updateGL() ) );
    timer->start(33);

}

GLWidget::~GLWidget()
{
    SCT_DELETE(mMutex);
    SCT_DELETE_ARRAY(mPictureData);
}

QSize GLWidget::minimumSizeHint() const
{
    return QSize(50, 50);
}

QSize GLWidget::sizeHint() const
{
    return QSize(200, 200);
}


void GLWidget::initializeGL()
{
}

void GLWidget::updatePicture(const void*d, const int w, const int h)
{
    CAutoLock locker(mMutex);

    if((w != mPictureWidth) || (h != mPictureHeight))
    {
        SCT_DELETE_ARRAY(mPictureData);

        mPictureWidth = w;
        mPictureHeight = h;
        mPictureData = new uint8_t[w*h*4];
    }

    memcpy(mPictureData, d, w*h*4);
}

void GLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();
    ///delete old texture and create a new one
    if(mNeedDeleteTexture)
    {
        glDeleteTextures(1,mTextures);
        mNeedDeleteTexture = 0;
    }

    glGenTextures(1, mTextures);
    mNeedDeleteTexture = 1;

    glBindTexture(GL_TEXTURE_2D, mTextures[0]);

    GLint mx;
    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mx);
//    SCT_LOGD("GL_MAX_TEXTURE_SIZE:%d\n", mx);
    mx = 1920;

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mx, mx, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);


    mMutex->lock();
    int w = mPictureWidth;
    int h = mPictureHeight;
    uint8_t * pic_data = mPictureData;
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pic_data);
    mMutex->unlock();

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


    GLfloat textureCoords[8] =
    {
            0.0f, 1.0f,
            1.0f, 1.0f,

            0.0f, 0.0f,
            1.0f, 0.0f,
    };


    textureCoords[0] = 0.0;			textureCoords[1] = (1.0*h)/mx;
    textureCoords[2] = (1.0*w)/mx;	textureCoords[3] = (1.0*h)/mx;
    textureCoords[4] = 0.0;			textureCoords[5] = 0.0;
    textureCoords[6] = (1.0*w)/mx;	textureCoords[7] = 0.0;

    glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);

    float vertices[] =           //2
    {
            -1.0f, -1.0f,
            1.0f, -1.0f,
            -1.0f,  1.0f,
            1.0f,  1.0f
    };

    float x = 1;
    float y = 1;

    float winRatio = (1.0* size().height())/(1.0* size().width());
    float picRatio = (1.0*h) / w;

    if(winRatio > picRatio)
    {
        x = 1;
        y = picRatio;
    }
    else
    {
        x = 1 * (winRatio/picRatio);
        y = winRatio;
    }


    vertices[0] = -x;	vertices[1] = -y;
    vertices[2] = x;	vertices[3] = -y;
    vertices[4] = -x;	vertices[5] = y;
    vertices[6] = x;	vertices[7] = y;

    glVertexPointer(2, GL_FLOAT, 0, vertices);

    glEnable(GL_TEXTURE_2D);

//    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_SRC_COLOR);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
}

void GLWidget::resizeGL(int width, int height)
{
    int w = width;
    int h = height;

    glDisable(GL_DITHER);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

//    if(t)
//    {
//        glClearColor(0, 0, 0, 0);
//    }
//    else
//    {
        glClearColor(1, 1, 1, 1);
//    }

    glEnable(GL_CULL_FACE);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);

//    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float x = 1.0;
    float y = (1.0 * h)/w;

    //in the center
    glOrtho(-x, x, -y, y, 1, -1);

    glViewport(0, 0, w, h);
}
